package base.value;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;



public abstract class Value<T> implements IValue<T> {

	private T value;
	private final Class<?> type;
	
	public Value() {
		this.value = null;
		this.type = this.getClass().getAnnotation(ValueType.class).type();
	}
	
	public Value(T v) {
		this.value = v;
		this.type = this.getClass().getAnnotation(ValueType.class).type();
	}
	
	public Value(Value<T> v) {
		this.value = v.value;
		this.type = this.getClass().getAnnotation(ValueType.class).type();
	}
	
	@Override
	public T get() {
		return value;
	}

	@Override
	public void set(T val) {
		this.value = val;	
	}

	@Override
	public boolean isHasType(Class<?> expType){
		return this.type.equals(expType);
	}
	
	@Override
	public Class<?> getValueType(){
		return type;
	}
	
	@Retention(value=RetentionPolicy.RUNTIME)
	@Target(value = ElementType.TYPE)
	@interface ValueType {
		Class<?> type();
	}
	
	@ValueType(type=java.lang.String.class)
	public static class String extends Value<java.lang.String>{
		public String() {
			super();
		}

		public String(java.lang.String string) {
			super(string);
		}
	}
	
	@ValueType(type=java.lang.Integer.class)
	public static class Integer extends Value<java.lang.Integer>{
		public Integer() {
			super();
		}

		public Integer(java.lang.Integer v) {
			super(v);
		}
	}
	
	
	@ValueType(type=base.UserObject.class)
	public static class UserObject extends Value<base.UserObject>{
		public UserObject() {
			
			super();
		}

		public UserObject(base.UserObject v) {
			super(v);
		}
	}
	
	@ValueType(type=java.util.UUID.class)
	public static class UUID extends Value<java.util.UUID>{
		public UUID() {
			
			super();
		}

		public UUID(java.util.UUID v) {
			super(v);
		}
	}


}
